;;(load "../sys/sys.scm")

;;(define cyl-loc 0)

(define-macro (next-loc)
  `(let ((loc (+ n 1)))
     (if (>= loc len)
	 (begin
	   (set! cyl-loc len)
	   #f)
	 loc)))
(define-macro (third-loc)
  `(let ((loc (+ n 2)))
     (if (>= loc len)
	 (begin
	   (set! cyl-loc len)
	   #f)
	 loc)))

(define (match-char-1 str n c)
  (let ((len (string-length str)))
    (if (integer? n)
	(if (< n len)
	    (if (char=? (string-ref str n) c)
		(begin
		  (set! cyl-loc n)
		  n)
		(match-char-1 str (next-loc) c))
	    (begin
	      (set! cyl-loc len)
	      #f))
	#f)
    ))

(define (match-char-with-slash-in-deli-or-include str n c  deli-f in-flag)
  (let ((len (string-length str)))
    (if (integer? n)
	(if (< n len)
	    (let ((ch (string-ref str n)))
	      (if (and deli-f (deli-f ch))
		  (if in-flag
		      (begin
			(set! cyl-loc n)
			#f)
		      (begin
			(set! cyl-loc (- n 1))
			#f))
		  (if (char=? ch c)
		      (if in-flag
			  (begin
			    (set! cyl-loc n)
			    ;;(y-or-n "t1:in-flag=~a,n=~a \n" in-flag n)
			    n)
			  (begin
			    (set! cyl-loc (- n 1))
			    ;;(y-or-n "t2:in-flag=~a,n=~a \n" in-flag n)
			    (- n 1)))
		      (if (char=? ch #\\)
			  (match-char-with-slash-in-deli-or-include str (third-loc) c  deli-f in-flag)
			  (match-char-with-slash-in-deli-or-include str (next-loc) c  deli-f in-flag))
		  )))
	    (begin
	      (set! cyl-loc len)
	      #f))
	  #f)
    ))
	
(define (match-char-in-deli-or-include str n c deli-f in-flag)
  ;;(y-or-n "in-flag=~a\n" in-flag)
  (let ((len (string-length str)))
    (if (integer? n)
	(if (< n len)
	    (let ((ch (string-ref str n)))
	      (if (and deli-f (deli-f ch))
		 (if in-flag
		      (begin
			(set! cyl-loc n)
			#f)
		      (begin
			(set! cyl-loc (- n 1))
			#f))
		 (if  (char=? ch c)
		      (if in-flag
			  (begin
			    (set! cyl-loc n)
			    ;;(y-or-n "tt1:in-flag=~a,n=~a \n" in-flag n)
			    n)
			  (begin
			    (set! cyl-loc (- n 1))
			    ;;(y-or-n "tt2:in-flag=~a,n=~a \n" in-flag n)
			    (- n 1)))
		      (match-char-in-deli-or-include str (next-loc) c deli-f in-flag))
		  ))
	    (begin
	      (set! cyl-loc len)
	      #f))
	#f)
    ))
(define (match-char-no-slash-include str n c)
  (match-char-in-deli-or-include str n c #f #t))
(define (match-char-include str n c)
  (match-char-with-slash-in-deli-or-include str n c #f #t))
(define (match-char-no-slash str n c)
  (match-char-in-deli-or-include str n c #f #f))
(define (match-char str n c)
  (match-char-with-slash-in-deli-or-include str n c  #f #f))
(define (match-char-deli str n c deli-f)
  (match-char-with-slash-in-deli-or-include str n c  deli-f #f))
(define (match-char-no-slash-include str n c)
  (match-char-in-deli-or-include str n c #f #t))
(define (match-char-deli-include str n c deli-f)
  (match-char-with-slash-in-deli-or-include str n c  deli-f #t))



(define (match2char-with-slash-in-deli-or-include str n c1 c2 deli-f in-flag)
   (let ((len (string-length str)))
    (if (integer? n)
	(if (< n len)
	    (let ((ch1 (string-ref str n))
		  (ch2 #f)
		  )
	      (if (and deli-f (deli-f ch1))
		  (if in-flag
		      (begin
			(set! cyl-loc (+ n 1))
			#f)
		      (begin
			(set! cyl-loc (- n 1))
			#f))
		  (if (< (+ n 1) len)
		      (begin
			(set! ch2 (string-ref str (+ n 1)))
			(if (and (char=? ch1 c1)(char=? ch2 c2))
			    (if in-flag
				(begin
				  (set! cyl-loc (+ n 1))
				  ;;(y-or-n "t1:in-flag=~a,n=~a \n" in-flag n)
				  (+ n 1))
				(begin
				  (set! cyl-loc (- n 1))
				  ;;(y-or-n "t2:in-flag=~a,n=~a \n" in-flag n)
				  (- n 1)))
			    (if (not (and deli-f (deli-f ch2)))
				(if (char=? ch1 #\\)
				    (match2char-with-slash-in-deli-or-include  str (third-loc) c1 c2  deli-f in-flag)
				    (match2char-with-slash-in-deli-or-include str (next-loc) c1 c2  deli-f in-flag))
				(begin
				  (set! cyl-loc (+ n 1))
				  #f))))
		      (begin
			(set! cyl-loc len)
			#f)
		  )))
	    (begin
	      (set! cyl-loc len)
	      #f))
	  #f)
    ))
(define (match-string-with-slash-in-deli-or-include str n s deli-f in-flag)
  ;;string need to match must be not include deli-char.
   (let ((len (string-length str))(l (string-length s)))
    (if (integer? n)
	(if (<= (+ n l) len)
	    (let ((ch (string-ref str n))(st (substring str n (+ n l))))
	      (if (and deli-f (deli-f ch))
		  (if in-flag
		      (begin
			(set! cyl-loc n)
			#f)
		      (begin
			(set! cyl-loc (- n 1))
			#f))
		  (if (string=? st s)
		      (if in-flag
			  (begin
			    (set! cyl-loc (+ n l))
			    ;;(y-or-n "t1:in-flag=~a,n=~a \n" in-flag n)
			    (+ n l))
			  (begin
			    (set! cyl-loc n)
			    ;;(y-or-n "t2:in-flag=~a,n=~a \n" in-flag n)
			    n))
		      (if (char=? ch #\\)
			  (match-string-with-slash-in-deli-or-include  str (third-loc) s  deli-f in-flag)
			  (match-string-with-slash-in-deli-or-include str (next-loc) s  deli-f in-flag))
		  )))
	    (begin
	      (set! cyl-loc len)
	      #f))
	  #f)
    ))
(define (match2char str n c1 c2)
 (match2char-with-slash-in-deli-or-include str n c1 c2 #f #t))
(define (match-str str n s)
  (let ((res  (match-string-with-slash-in-deli-or-include str n s #f #t)))
    (if (integer? res) (- res 1) res)))
(define (match2char-no-include str n c1 c2)
  (match2char-with-slash-in-deli-or-include str n c1 c2 #f #f))
(define (match-str-no-include str n s)
  (let ((res (match-string-with-slash-in-deli-or-include str n s #f #f)))
    (if (integer? res) (- res 1) res)))

(define (match-the-string str n)
  ;;(y-or-n "string:n=~a,cyl-loc=~a\n" n cyl-loc)
  (match-char-include str n #\"))
(define (rd-sexp-deli c)
  (or (char=? c #\")(char=? c #\()(char=? c #\[)(char=? c #\])(char=? c #\{)(char=? c #\})))
(define (rd-yexp-deli c)
  (or (char=? c #\")(char=? c #\()(char=? c #\))(char=? c #\[)(char=? c #\{)(char=? c #\})))
(define (rd-lexp-deli c)
  (or (char=? c #\")(char=? c #\()(char=? c #\))(char=? c #\[)(char=? c #\])(char=? c #\{)))
(define (match-the-sexp str n)
  (let ((len (string-length str))(i (match-char-deli-include str n #\) rd-sexp-deli)))
    ;;(y-or-n "sexp:n=~a,i=~a,cyl-loc=~a\n" n i cyl-loc)
    (cond
     ((integer? i) i)
     ((and (not i)(integer? cyl-loc)(>= cyl-loc n)(< cyl-loc len))
      (let ((c (string-ref str cyl-loc)))
	(cond
	 ((char=? c #\")
	  (match-the-sexp str (+ (match-the-string str (+ cyl-loc 1)) 1)))
	 ((char=? c #\()
	  (match-the-sexp str (+ (match-the-sexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\[)
	  (match-the-sexp str (+ (match-the-yexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\{)
	  (match-the-sexp str (+ (match-the-lexp str (+ cyl-loc 1)) 1)))
	 ((or (char=? c #\))(char=? c #\])(char=? c #\}))
	  #f))))
     (else #f))))
(define (match-the-yexp str n)
  (let ((len (string-length str))(i (match-char-deli-include str n #\] rd-yexp-deli)))
    ;;(y-or-n "yexp:i=~a,cyl-loc=~a\n" i cyl-loc)
    (cond
     ((integer? i) i)
     ((and (not i)(integer? cyl-loc)(> cyl-loc n)(< cyl-loc len))
      (let ((c (string-ref str cyl-loc)))
	(cond
	 ((char=? c #\")
	  (match-the-yexp str (+ (match-the-string str (+ cyl-loc 1)) 1)))
	 ((char=? c #\()
	  (match-the-yexp str (+ (match-the-sexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\[)
	  (match-the-yexp str (+ (match-the-yexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\{)
	  (match-the-yexp str (+ (match-the-lexp str (+ cyl-loc 1)) 1)))
	 ((or (char=? c #\))(char=? c #\])(char=? c #\}))
	  #f))))
     (else #f))))
(define (match-the-lexp str n)
  (let ((len (string-length str))(i (match-char-deli-include str n #\} rd-lexp-deli)))
    ;;(y-or-n "lexp:i=~a,cyl-loc=~a\n" i cyl-loc)
    (cond
     ((integer? i) i)
     ((and (not i)(integer? cyl-loc)(> cyl-loc n)(< cyl-loc len))
      (let ((c (string-ref str cyl-loc)))
	(cond
	 ((char=? c #\")
	  (match-the-lexp str (+ (match-the-string str (+ cyl-loc 1)) 1)))
	 ((char=? c #\()
	  (match-the-lexp str (+ (match-the-sexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\[)
	  (match-the-lexp str (+ (match-the-yexp str (+ cyl-loc 1)) 1)))
	 ((char=? c #\{)
	  (match-the-lexp str (+ (match-the-lexp str (+ cyl-loc 1)) 1)))
	 ((or (char=? c #\))(char=? c #\])(char=? c #\}))
	  #f))))
     (else #f))))

	
     
    
 
  
